/**
 * 
 */
package com.ms.service.module.fish;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;
import com.ms.game.gmtool.ISlotGameServerProcesserToGMTool;
import com.ms.game.slot.base.ISlotGameServerProcesser;
import com.ms.game.slot.base.message.SGmtoolCleanGameSeatStatusRequest;
import com.ms.game.slot.base.message.SSlotCommonDmSeatPlayerInfoRequest;
import com.ms.game.slot.base.message.SlotBasicGameMessageRequest;
import com.ms.game.slot.base.message.SlotGameDoSeatVerifyRequest;
import com.ms.game.slot.base.message.SlotGameLeaveBackRequest;
import com.ms.game.slot.base.message.SlotGameLeaveRequest;
import com.ms.game.slot.base.message.SlotGameLeaveResponse;
import com.ms.player.Player;
import com.ms.service.module.account.message.SSessionCloseNotify;
import com.ms.service.module.fish.db.UsrGameLog;
import com.ms.service.module.fish.game.FishDesk;
import com.ms.service.module.fish.game.FishGame;
import com.ms.service.module.fish.game.FishGlobal;
import com.ms.service.module.fish.game.FishUser;
import com.ms.service.module.fish.game.GameConf;
import com.ms.service.module.fish.game.GameUser;
import com.ms.service.module.fish.message.FishRequestWrap;
import com.ms.service.module.fish.utils.FishGameUtils;
import com.ms.service.module.fish.utils.GoConstant;
import com.ms.service.module.zone.BasicZone;
import com.ms.service.module.zone.message.SGameJackPotLockResponse;
import com.xpec.c4.game.utility.GUID;
import com.xpec.c4.message.MessageTypes;

/**
 * 捕鱼功能類別
 * 
 * @author TW15010
 */
public class FishProcessor extends BasicZone implements ISlotGameServerProcesser, ISlotGameServerProcesserToGMTool {
	/**
	 * 認證過期時間
	 */
	public static final int VERIFY_EXPRIED_TIME = 20;

	/** log4j object */
	private static final Logger logger = LoggerFactory.getLogger(FishProcessor.class);


	@Override
	public void onPlayerLogin(Player player) {
		super.onPlayerLogin(player);
		
		enterMyArea(player);
	}

	/**
	 * 开始进入捕鱼领空，后续逻辑交给捕鱼module
	 * @param player
	 * @return 
	 */
	private MySession enterMyArea(Player player) {
		MySession session = new C4Session(player.getSessionID());
		FishGlobal.addSession(session );
		
		FishUser fuser = new FishUser(player);
		GameUser user = new GameUser(fuser);
		session.setUser(user);
		FishGlobal.addUser(player.getGuid(), session);
		
		return session;
	}
	
	/**
	 * 离开捕鱼领空
	 * @param player
	 * @param session 
	 */
	private void outMyArea(MySession session) {
		FishGlobal.removeSession(session);
	}

	@Override
	public void onPlayerDisconnect(SSessionCloseNotify notify) {
		GUID sessionId = notify.getSessionId();
		MySession mySession = FishGlobal.getSessionBySid(sessionId);
		if(mySession != null){
			FishGameUtils.outRoom(mySession.getUser(),2);
			outMyArea(mySession);
		}
		super.onPlayerDisconnect(notify);
	}

	/**
	 * 啟動要再這個 module 執行的遊戲核心
	 */
	public void initialGameCore() {
//		for (BacrTableSettingInfo info : BacrMachineSetting.getInstance().getTableList()) {
//			// 牌桌 id
//			String tableId = info.getTableId();
//
//			// 執行這個遊戲核心的 module
//			String executeModule = ConsistentGroupName.lookUpByString(ModuleName.GROUP_BACR, tableId);
//
//			// 目前的 module
//			String curModule = getOwnerModule().getModuleName();
//
//			// 目前的 module 是執行此核心的 module 就啟動他
//			if (curModule.equals(executeModule)) {
//				
//			} // if (curModule.equals(executeModule)) {
//		} // for (BacrTableSettingInfo info : ...
	}
	
	public void enterRoom(FishRequestWrap request) {
		String guid = request.getString();
		Player player = getPlayer(GUID.parseUUID(guid));
		if(player == null){
			// test
			player = new Player();
			player.setSessionID(request.getSessionId());
			player.setGuid(GUID.parseUUID(guid));
			player.setgoldCoin(new BigDecimal(100000));
		}
		MySession mySession = enterMyArea(player );
		
		SendUtil.send100(mySession,mySession.getUser());
		// 大厅信息
		SendUtil.send102(mySession.getUser());
	}
	
	// 预占位逻辑
	public void preEnter(MySession session,FishRequestWrap data){
		GameUser user = session.getUser();
		int deskId = data.getInt();
		int index = data.getByte();
		if(index < GoConstant.CHAIR_SIZE){
			FishDesk desk = FishGlobal.getDesk(deskId);
			if(desk == null) return;
			boolean isOk = false;
			synchronized (desk) {
				isOk = desk.preEnter(user,index);
			}
			if(isOk){
				SendUtil.send110(session, deskId,index);
			}else{
				SendUtil.send110(session,-1, -1);
			}
		}
	}
	
	public void enterFishGame(MySession session,FishRequestWrap data) {
		GameUser user = session.getUser();
		int deskId = data.getInt();
		int index = data.getByte();
		if(index < GoConstant.CHAIR_SIZE){
			// 加入房间
			FishDesk desk = FishGlobal.getDesk(deskId);
			if(desk == null) return;
			boolean isNew = false;
			synchronized (desk) {
				if(!desk.addUser(user,index)) {
					// 已经有人
					return;
				}
				isNew = desk.enterGame(user);
			}
			SendUtil.send111(session, user); // 发送给当前玩家
			SendUtil.send112(user); // 通知其他玩家有人进入
			// 广播给大厅的人更新桌子信息
			SendUtil.send103(desk, index);
			if(isNew) {
				// 开始游戏
				SendUtil.send205(desk, desk.getGame());
			}else {
				// 同步游戏状态
				SendUtil.send113(session, user);
			}
		}
	}
	
	public void outFishGame(MySession session, FishRequestWrap request) {
		if(session != null){
			FishGameUtils.outRoom(session.getUser(),request.getByte());
			outMyArea(session);
		}
	}

	public void fire(MySession session, FishRequestWrap data) {
		GameUser user = session.getUser();
		int x = data.getInt();
		int y = data.getInt();
		
		int battery = user.getBattery();
		FishGame game = user.getGame();
		if(game == null) return;
		if(battery == GoConstant.BATTERY_TYPE_1 || battery == GoConstant.BATTERY_TYPE_2) return;
		boolean isFire = FishGameUtils.fire(user, 0, x, y,battery);
		
		// 核弹炮必然打中，同时执行捕鱼逻辑
		if(isFire && battery == GoConstant.BATTERY_TYPE_13){
			if(!user.catchFish(GoConstant.BATTERY_TYPE_13,0)) return ;
			List<Integer> scripts = game.getInFishs();
			FishGameUtils.catchMultFish(user, GoConstant.BATTERY_TYPE_13, scripts,0);
			
		}
	}

	public void catchFish(MySession session, FishRequestWrap data) {
		GameUser user = session.getUser();
		int bullet = data.getByte();
		int scriptId = data.getInt();
		FishGame game = user.getGame();
		if(game == null) return;
		if(!user.catchFish(bullet,scriptId)) return ;
		
		UsrGameLog log = FishGameUtils.catchFish(user,game, scriptId, bullet,0);
		if(log != null && log.getRate() >= 0){
			if(log.battary() > 0){
				if(logger.isInfoEnabled()){
					logger.info("切换炮台：{}-{}", user.getId(),log.battary());
				}
				SendUtil.send202(user.getDesk(),bullet, log,user);
				// 由前端触发
//				SendUtil.send203(user);
			}else {
				SendUtil.send202(user.getDesk(),bullet, log,null);
			}
		}
	}

	public void changBattery(MySession session, FishRequestWrap data) {
		GameUser user = session.getUser();
		int battery = data.getByte();
		
		FishGame game = user.getGame();
		if(game == null) return;
		if(battery == GoConstant.BATTERY_TYPE_2) return;
		
		if(battery <= GoConstant.BATTERY_TYPE_1){
			// 普通切换或特殊炮到期
			user.setBattery(battery);
			SendUtil.send203(user);
		}else if(battery > GoConstant.BATTERY_TYPE_2){
			// 切换掉落的特殊炮
			if(user.exchangeBattery(battery)){
				SendUtil.send203(user);
			}
		}
	}

	public void changeRate(MySession session, FishRequestWrap data) {
		GameUser user = session.getUser();
		int rate = data.getInt();
		
		FishGame game = user.getGame();
		if(game != null && user.getBattery() <= GoConstant.BATTERY_TYPE_1){
			user.setBatteryRate(rate);
			
			SendUtil.send204(user);
		}
	}

	public void lockFire(MySession session, FishRequestWrap data) {
		GameUser user = session.getUser();
		int scriptId = data.getInt();
		
		if(user.getBattery() != GoConstant.BATTERY_TYPE_1) return;
		boolean isFire = FishGameUtils.fire(user, scriptId, 0, 0,GoConstant.BATTERY_TYPE_1);
		if(!isFire) return;
		// 锁定炮必然打中，同时执行捕鱼逻辑
		UsrGameLog log = FishGameUtils.catchFish(user, user.getGame(), scriptId, GoConstant.BATTERY_TYPE_1,0);
		if(log != null && log.getRate() >= 0){
			if(log.battary() > 0){
				SendUtil.send202(user.getDesk(),GoConstant.BATTERY_TYPE_1, log,user);
				// 由前端触发
//				SendUtil.send203(user);
			}else {
				SendUtil.send202(user.getDesk(),GoConstant.BATTERY_TYPE_1, log,null);
			}
		}
	}

	public void catchMultFish(MySession session, FishRequestWrap data) {
		GameUser user = session.getUser();
		// 12-电磁波，13-核弹，21-100像素爆炸，22-闪电链
		int bullet = data.getByte();
		int len = data.getInt();
		FishGame game = user.getGame();
		if(game == null) return;
		List<Integer> scripts = Lists.newArrayList();
		for(int i=0;i<len;i++){
			scripts.add(data.getInt());
		}
		if(!user.catchFish(bullet,0)) return ;
		
		FishGameUtils.catchMultFish(user, bullet, scripts,0);
		
	}

	public void laba(MySession session, FishRequestWrap data) {
		GameUser user = session.getUser();
		FishGame game = user.getGame();
		if(game == null || user.getLaba() <= 0) return;
		
		FishUser gameInfo = user.getUser();
		UsrGameLog log = new UsrGameLog(gameInfo);
		
		int rate = GameConf.getLabaReward(FishGlobal.sysCurrHave.get());
		log.setScriptId(999);
		log.setRate(rate);
		Integer addCoin = rate*user.getLaba();
		user.setLaba(0);
		log.setAddCoin(addCoin );
		if(addCoin > 0) {
			gameInfo.addCoin(addCoin);
			FishGameUtils.saveDb(gameInfo,log);
			
			if(!user.isRobo()) {
				FishGlobal.sysCurrHave.addAndGet(-addCoin);
			}
		}
		SendUtil.send208(user,log);
	}
	
	public void roomRewards(MySession session, FishRequestWrap data) {
		GameUser user = session.getUser();
		FishDesk desk = user.getDesk();
		
		SendUtil.send209(session,desk);
		
	}

	public void loadConf(MySession session, FishRequestWrap data) {
		int version = data.getInt();
		SendUtil.send300(session,version);
	}
	
	/**
	 * 掉落炮弹接口
	 */
	public void dropShell(MySession session, int bullet) {
		GameUser user = session.getUser();
		
		user.dropShell(bullet);
		
		SendUtil.send210(session,user);
	}
	
	
	/*********************************
	 * 框架相关实现 ↓↓↓
	 *********************************/

	/**
	 * 玩家入座驗證
	 * 
	 * @param request
	 */
	@Override
	public void revDoSeatVerify(SlotGameDoSeatVerifyRequest request) {
		String halltype = request.getHalltype();
		Player player = this.baseaction.getPlayer();
		String guid = player.getGuid().toString();
		GUID sessionid = this.baseaction.getSessionID();

	}

	@Override
	public void revDisConnect(SSessionCloseNotify request) {
		// 直接刪除資料
		onPlayerDisconnect(request);
	}

	/**
	 * 玩家離座
	 */
	public void revGameLeave(SlotGameLeaveRequest request) {
		String halltype = request.getHalltype();
		Player player = this.baseaction.getPlayer();
		String srcID = baseaction.getModuleID();
		GUID sessionid = baseaction.getSessionID();


	}

	/**
	 * dm 離座處理完回呼game server
	 * 
	 * @param request
	 */
	@Override
	public void revLeaveSeatBack(SlotGameLeaveBackRequest request) {
		GUID sessionid = request.getSessionid();
		if (sessionid == null) {
			return;
		}

		SlotGameLeaveResponse response = new SlotGameLeaveResponse();
		response.setErrorCode(request.getErrorCode());
		sendMessageToClient(sessionid, MessageTypes.S_SLOT_GAMELEAVEBACK, response);
	}

	@Override
	public void revGmtoolCleanGameSeatStatus(SGmtoolCleanGameSeatStatusRequest request) {
	}
	@Override
	public void revClientStopAutoSpinOptionQuery() {
	}

	// -------------------↓新框架以下函式己不使用↓--------------------------------------
	
	@Override
	public void revClientGameSeatVerify(SlotBasicGameMessageRequest request) {}
	@Override
	public void revClientGameSeatVerifyBack(SlotBasicGameMessageRequest request) {}
	@Override
	public void revGameLeaveSeat(SlotBasicGameMessageRequest request) {}
	@Override
	public void revGameLeaveSeatBack(SlotBasicGameMessageRequest request) {}
	@Override
	public void revClientSpin(SlotBasicGameMessageRequest request) {}
	@Override
	public void revGameJackPotLockBack(SGameJackPotLockResponse request) throws NoSuchMethodException,
			SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {}
	@Override
	public void revGameHistoryRecord(SlotBasicGameMessageRequest request) {}
	@Override
	public void revSeatPlayerInfoRequest(GUID sessionId, SSlotCommonDmSeatPlayerInfoRequest request) {}
	@Override
	public void revSeatVerifyInfoRequest(SlotBasicGameMessageRequest request) {}



}
